import { fromEvent, merge } from 'rxjs'
import { map, tap } from 'rxjs/operators'

export interface SocketMessage<T> {
  type: string
  data: T
}
export type SocketRoomTypes =
  | 'joinRoom' // 加入房间
  | 'sendToRoom' // 向房间发送消息
  | 'leaveRoom' // 离开房间
export class SocketRoom {
  roomId: number
  roomName: string
  msgType: SocketRoomTypes[] = []

  constructor(id: number, msgType: SocketRoomTypes[] = ['joinRoom', 'sendToRoom', 'leaveRoom']) {
    this.roomId = id
    this.roomName = `room${this.roomId}`
    this.msgType = msgType
  }

  join(socket: SocketIO.Socket, data: any) {
    socket.join(this.roomName)
    this.send(socket, { type: 'joinRoom', data: data })
    const msgs = this.msgType.map(res =>
      fromEvent(socket, res).pipe(
        map(data => ({
          type: res,
          data: data
        }))
      )
    )
    // 监听消息
    merge(...msgs)
      .pipe(
        // 处理消息 然后广播
        tap(res => {
          this.send(socket, res)
        })
      )
      .subscribe()
  }

  send<T>(socket: SocketIO.Socket, msg: SocketMessage<T>) {
    socket.to(this.roomName).emit(msg.type, msg.data)
    socket.emit(msg.type, msg.data)
  }
}
